import {
    TabAddRequests,
    TabColumnKeys,
    TabColumnNames,
    TabDeleteRequests,
    TableButtonName,
    TableColumnTypes,
    TableHeaders,
    TabPageCapacities,
    TabQueryCntRequests,
    TabQueryRequests,
    TableColumnRule,
} from "./tableconfig.js";
import {
    convertUTCToLocalDate,
    convertLocalDateToUTCSeconds,
} from "./util.js";
import {queryGMList} from "./apidata.js";

export function renderTable(tabName) {
    TableSingletonInstance.Render(tabName);
}

const TableSingleton = (function () {
    let instance;

    return {
        getInstance: function () {
            if (!instance) {
                instance = table();
            }
            return instance;
        }
    }
})();

const TableSingletonInstance = TableSingleton.getInstance();

function table() {
    let sharedCurrentTabName = ''; // 当前页签名称
    let sharedTotalCnt = 0; // 数据总条数
    let sharedTotalPages = 0; // 数据总页数
    let sharedCurrentPage = 0; // 当前页码
    let iconAddListenerFun = [];
    let sharedGMList = [];

    function Render(tabName) {
        sharedCurrentTabName = tabName;
        renderTableHeader();
        queryGMList().then(gms => {
            sharedGMList = gms;
            renderTableData();
            addIconAddClickListener();
        });
    }

    // 判断最后一页是否满
    function isLastPageFull() {
        return sharedTotalCnt % TabPageCapacities.get(sharedCurrentTabName) === 0
    }

    // 点击加号的回调函数
    function onClickAddIcon() {
        // 定位到最后一页
        if (isLastPageFull()) {
            sharedTotalPages++;
            sharedCurrentPage = sharedTotalPages;
        } else {
            sharedCurrentPage = sharedTotalPages;
        }
        showPagination();
        goToPage().then(() => {
            addRowForInput();
        });
    }

    // 给加号添加点击监听事件
    function addIconAddClickListener() {
        const iconAdd = document.getElementById('iconAdd'); // 获取图像元素

        iconAddListenerFun.map((v) => iconAdd.removeEventListener('click', v));
        iconAddListenerFun = [];

        iconAdd.addEventListener('click', onClickAddIcon);
        iconAddListenerFun.push(onClickAddIcon);
    }

    // 删除按钮点击反馈
    function onDeleteButton(deleteButton) {
        // 获取本行的数据id
        let tr = deleteButton.parentNode.parentNode;
        let id = parseInt(tr.dataset.id);

        // 调用服务器API删除数据
        let deleteRequest = TabDeleteRequests.get(sharedCurrentTabName);
        deleteRequest(id).then(() => {
            // 修改页数和条数
            decreaseSharedTotalCnt();

            // 显示当前页
            showPagination();
            goToPage().then(() => {
            });
        });
    }

    function decreaseSharedTotalCnt() {
        sharedTotalCnt--;
        sharedTotalPages = Math.ceil(sharedTotalCnt / TabPageCapacities.get(sharedCurrentTabName));
        if (sharedCurrentPage > sharedTotalPages) {
            sharedCurrentPage = sharedTotalPages;
        }
    }

    function increaseSharedTotalCnt() {
        sharedTotalCnt++;
        sharedTotalPages = Math.ceil(sharedTotalCnt / TabPageCapacities.get(sharedCurrentTabName));
        if (sharedCurrentPage > sharedTotalPages) {
            sharedCurrentPage = sharedTotalPages;
        }
    }

    // 保存按钮点击反馈
    function onSaveButton(saveButton) {
        let newRow = saveButton.parentNode.parentNode;
        let cells = newRow.querySelectorAll('td');
        let formData = [];
        for (let i = 0; i < cells.length; i++) {
            // 检查单元格中的第一个子元素的类型
            let cell = cells[i];
            const elementType = cell.firstElementChild.nodeName.toLowerCase();
            let value;

            // 如果是输入框，则获取输入框的值
            if (elementType === 'input') {
                value = cell.querySelector('input').value;
            }
            // 如果是下拉列表，则获取下拉列表选中的值
            else if (elementType === 'select') {
                value = cell.querySelector('select').value;
            }

            // 将值添加到数组中
            formData.push(value);
        }
        let addRequest = TabAddRequests.get(sharedCurrentTabName);
        addRequest(...formData).then(() => {
            // 增加总记录数和页数
            increaseSharedTotalCnt();

            for (let i = 0; i < formData.length; i++) {
                let cell = cells[i];
                let cellType = TableColumnTypes.get(sharedCurrentTabName)[i];

                if (cellType === "button") {
                    continue
                }

                let span = document.createElement("span");
                cell.replaceChild(span, cell.firstElementChild);

                span.textContent = formData[i];

                if (cellType === "date") {
                    span.textContent = convertUTCToLocalDate(convertLocalDateToUTCSeconds(formData[i]));
                }

            }

            let td = saveButton.parentNode

            // 删除保存按钮
            saveButton.parentNode.removeChild(saveButton);

            // 添加一个 Delete 按钮
            let deleteButton = document.createElement('button');
            td.appendChild(deleteButton);
            deleteButton.textContent = TableButtonName.Delete;
            deleteButton.addEventListener('click', function () {
                onDeleteButton(deleteButton);
            });
        });
    }


    // 创建新的一行, 等待用户输入数据
    function addRowForInput() {
        let types = TableColumnTypes.get(sharedCurrentTabName);
        let placeholders = TableHeaders.get(sharedCurrentTabName);

        let tbody = document.querySelector("#data-table > tbody")
        let newRow = document.createElement('tr');
        tbody.appendChild(newRow);

        for (let i = 0; i < types.length; i++) {
            let td = document.createElement("td");
            newRow.appendChild(td);

            switch (types[i]) {
                case "date":
                    let dateInput = document.createElement("input");
                    td.appendChild(dateInput);
                    dateInput.type = types[i];
                    dateInput.placeholder = placeholders[i];
                    dateInput.classList.add("input-style");
                    dateInput.value = "";
                    break;
                case "text":
                    let textInput = document.createElement("input");
                    td.appendChild(textInput);

                    textInput.addEventListener('click', function () {
                        let funcRule = TableColumnRule.get(sharedCurrentTabName)[i];
                        if (funcRule) {
                            textInput.value = funcRule(textInput.value);
                        }
                    });

                    textInput.type = types[i];
                    textInput.placeholder = placeholders[i];
                    textInput.classList.add("input-style");
                    textInput.value = "";
                    break;
                case "select":
                    let adminSelect = document.createElement("select");
                    td.appendChild(adminSelect);
                    adminSelect.classList.add("admin-select");

                    sharedGMList.forEach(function (gm) {
                        let option = document.createElement("option");
                        option.classList.add("option");
                        option.value = gm;
                        option.text = gm;
                        adminSelect.appendChild(option);
                    });
                    break;
                case "button":
                    let saveButton = document.createElement("button");
                    td.appendChild(saveButton);

                    saveButton.textContent = TableButtonName.Save;
                    saveButton.addEventListener('click', function () {
                        onSaveButton(saveButton);
                    });
                    break;
                default:
                    break;
            }
        }
    }

    // 删除所有行
    function deleteRows() {
        let tbody = document.querySelector("#data-table > tbody")
        tbody.innerHTML = '';
    }

    // 渲染多行
    function renderRows(dataList) {
        for (let i = 0; i < dataList.length; i++) {
            renderRow(dataList[i]);
        }
    }

    // 创建新的一行用来显示
    function renderRow(data) {
        let types = TableColumnTypes.get(sharedCurrentTabName);
        let fields = TabColumnNames.get(sharedCurrentTabName);

        let tbody = document.querySelector("#data-table > tbody")
        let newRow = document.createElement('tr');
        tbody.appendChild(newRow);

        newRow.dataset.id = data[TabColumnKeys.get(sharedCurrentTabName)];

        for (let i = 0; i < types.length; i++) {
            let newTd = document.createElement("td");
            newRow.appendChild(newTd);

            switch (types[i]) {
                case "date":
                    let dateSpan = document.createElement("span");
                    newTd.appendChild(dateSpan);
                    dateSpan.textContent = convertUTCToLocalDate(data[fields[i]]);
                    break;
                case "text":
                case "select":
                    let newSpan = document.createElement("span");
                    newTd.appendChild(newSpan);
                    newSpan.textContent = data[fields[i]];
                    break;
                case "button":
                    let deleteButton = document.createElement('button');
                    newTd.appendChild(deleteButton);
                    deleteButton.textContent = TableButtonName.Delete;
                    deleteButton.addEventListener('click', function () {
                        onDeleteButton(deleteButton);
                    });
                    break;
                default:
                    break;
            }
        }
    }

    // 渲染表头
    function renderTableHeader() {
        // 修改表头
        let headers = TableHeaders.get(sharedCurrentTabName);
        let tr = document.querySelector("#data-table > thead > tr");
        let ths = tr.getElementsByTagName('th');
        let headersLen = headers.length;
        let thsLen = ths.length;

        // 先修改内容
        for (let i = 0; i < headersLen && i < thsLen; i++) {
            ths[i].textContent = headers[i];
        }
        // 不够了要在尾部添加
        if (thsLen < headersLen) {
            for (let i = thsLen; i < headersLen; i++) {
                let newTh = document.createElement('th');
                tr.appendChild(newTh);

                newTh.innerText = headers[i];
            }
        }
        // 多了要从尾部到头部逐个删
        if (thsLen > headersLen) {
            for (let i = thsLen - 1; i >= headersLen; i--) {
                tr.removeChild(ths[i]);
            }
        }
    }

    function renderTableData() {
        let queryCntRequest = TabQueryCntRequests.get(sharedCurrentTabName);
        if (queryCntRequest) {
            queryCntRequest().then(cnt => {
                if (cnt <= 0) {
                    deleteRows();
                    deletePagination();
                    return
                }

                sharedTotalCnt = cnt;
                sharedTotalPages = Math.ceil(cnt / TabPageCapacities.get(sharedCurrentTabName));
                sharedCurrentPage = 1;
                showPagination();
                goToPage().then(() => {
                });
            });
            return;
        }

        deleteRows();
        deletePagination();
    }

    // 定位到指定页
    function goToPage() {
        // 计算当前要显示的页列表
        let pages = getPagesToShow();
        let pageIndex = getPageIndex(pages);

        // 选中指定页
        let lis = document.querySelectorAll('#pagination-container ul li');
        for (let i = 0; i < lis.length; i++) {
            lis[i].classList.remove('active');
        }
        lis[pageIndex + 2].classList.add('active');

        // 先清空数据行
        deleteRows();

        // 调用服务器API查询数据
        let queryRequest = TabQueryRequests.get(sharedCurrentTabName);
        let pageCapacity = TabPageCapacities.get(sharedCurrentTabName);
        if (queryRequest) {
            return queryRequest(sharedCurrentPage, pageCapacity).then(records => {
                if (records) {
                    renderRows(records);
                }
            })
        }

        return Promise.resolve;
    }

    // 删除页面控件
    function deletePagination() {
        let pageContainer = document.getElementById('pagination-container');
        pageContainer.innerHTML = '';
    }

    // 显示页面控件
    function showPagination() {
        let pageContainer = document.getElementById('pagination-container');
        pageContainer.innerHTML = '';

        let ul = document.createElement('ul');
        pageContainer.appendChild(ul);

        ul.className = 'pagination';

        addPage(ul, 1, '首页');
        addPage(ul, Math.max(1, sharedCurrentPage - 1), '前一页');

        let pages = getPagesToShow();
        for (let i = 0; i < pages.length; i++) {
            let page = pages[i];
            addPage(ul, page, String(page));
        }

        addPage(ul, Math.min(sharedTotalPages, sharedCurrentPage + 1), '后一页');
        addPage(ul, sharedTotalPages, '尾页');
    }

    function addPage(ul, page, innerText) {
        let li = document.createElement('li');
        ul.appendChild(li);

        let a = document.createElement('a');
        li.appendChild(a);

        a.href = "#";
        a.innerText = innerText;
        a.onclick = function (e) {
            e.preventDefault();

            sharedCurrentPage = page;
            showPagination();
            goToPage().then(() => {
            });
        };
    }

    // 计算要显示的页数，总的原则是，显示当前页附近的10页(前4后5)
    function getPagesToShow() {
        let startPage;
        let endPage;
        const maxPageVisible = 10;

        if (sharedTotalPages <= maxPageVisible) {
            // 总页数少于10, 直接显示所有页码
            startPage = 1;
            endPage = sharedTotalPages;
        } else {
            if (sharedCurrentPage <= maxPageVisible / 2) {
                // 当前页数不超过5, 则默认显示1-10页
                startPage = 1;
                endPage = maxPageVisible;
            } else if (sharedCurrentPage + maxPageVisible / 2 <= sharedTotalPages) {
                // 当前页数超过了5, 且总页数很多, 则显示当前页前4后5页, 凑成10页
                startPage = sharedCurrentPage - maxPageVisible / 2 + 1;
                endPage = sharedCurrentPage + maxPageVisible / 2;
            } else {
                // 当前页接近总页数, 则保持显示尾页, 始终凑成有10页可显示数据
                startPage = sharedTotalPages - maxPageVisible + 1;
                endPage = sharedTotalPages;
            }
        }

        let pages = [];
        for (let i = startPage; i <= endPage; i++) {
            pages.push(i);
        }

        return pages;
    }

    function getPageIndex(pages) {
        let pageIndex = 0;
        for (let i = 0; i < pages.length; i++) {
            if (pages[i] === sharedCurrentPage) {
                pageIndex = i;
            }
        }

        return pageIndex;
    }

    return {Render};
}